using System;
using System.Collections.Generic;
using System.Text;
using System.IO.IsolatedStorage;
using System.IO;

namespace Zsa.Emulation.Config
{
    /// <summary>
    /// Stores multiple user or global configuration profiles that is persisted 
    /// to the disk.
    /// </summary>
    public class NesConfigurationStore : IList<NesConfigurationProfile>
    {

        #region Fields

        #region Constants
        /// <summary>
        /// Header for profile.
        /// </summary>
        internal const string ProfileHeader = "ZSA.NINTENDER.ALMR?ZNS";

        /// <summary>
        /// The default file name.
        /// </summary>
        internal const string DefaultFileName = "Config." + ProfileExtension;

        /// <summary>
        /// The extension for configuration profiles.
        /// </summary>
        internal const string ProfileExtension = "ZNS";
        #endregion Constants

        /// <summary>
        /// List of profiles.
        /// </summary>
        private List<NesConfigurationProfile> _Profiles;

        /// <summary>
        /// The default profile.
        /// </summary>
        private NesConfigurationProfile _DefaultProfile;
        /// <summary>
        /// The config filename.
        /// </summary>
        private string _FileName;

        /// <summary>
        /// The storage scope.
        /// </summary>
        private IsolatedStorageScope _Scope;

        /// <summary>
        /// The recently played games list.
        /// </summary>
        private MruList<string> _RecentList;

        /// <summary>
        /// The default profile index.
        /// </summary>
        private int _DefaultProfileIndex = 0;

        /// <summary>
        /// The last rom file path.
        /// </summary>
        private string _LastRomFilepath = @"E:\Dev\Nes Dev\Test Roms\";

        private string _NameTableImageOutputPath = @"E:\Dev\Nes Dev\Images\Name Table\";

        private string _PatternTableOutputPath = @"E:\Dev\Nes Dev\Images\Pattern Tables\";

        /// <summary>
        ///Paths of folders with roms.
        /// </summary>
        private string[] _RomPaths;

        #endregion Fields

        #region Constructor
        /// <summary>
        /// Initializes a new instance of the <see cref="T:NesConfigurationProfileStore"/> class.
        /// </summary>
        public NesConfigurationStore()
        {
            string _BasePath =
                Path.GetDirectoryName(typeof(NesConfigurationManager).Assembly.Location);
            _NameTableImageOutputPath = _BasePath + "\\Name Table\\";
            _PatternTableOutputPath = _BasePath + "\\Pattern Tables\\";
            _LastRomFilepath = _BasePath + "\\Test Roms\\";
            if (!Directory.Exists(_NameTableImageOutputPath))
            {
                try
                {
                    Directory.CreateDirectory(_NameTableImageOutputPath);
                }
                catch { }
            }
            if (!Directory.Exists(_PatternTableOutputPath))
            {
                try
                {
                    Directory.CreateDirectory(_PatternTableOutputPath);
                }
                catch { }
            }
            if (!Directory.Exists(_LastRomFilepath))
            {
                try
                {
                    Directory.CreateDirectory(_LastRomFilepath);
                }
                catch { }
            }
        }
        #endregion Constructor

        #region Properties

        /// <summary>
        /// Gets the name of the file.
        /// </summary>
        /// <value>The name of the file.</value>
        public string FileName
        {
            get
            {
                return _FileName;
            }
        }

        /// <summary>
        /// Gets the storage scope.
        /// </summary>
        /// <value>The storage scope.</value>
        public IsolatedStorageScope StorageScope
        {
            get
            {
                return _Scope;
            }
        }

        /// <summary>
        /// Gets the <see cref="T:NesConfigurationProfile"/> with the specified profile name.
        /// </summary>
        /// <value></value>
        public NesConfigurationProfile this[string profileName]
        {
            get
            {
                return _Profiles.Find(
                    delegate(NesConfigurationProfile profile)
                    {
                        return profile.Name == profileName;
                    }
                );
            }
        }

        /// <summary>
        /// Gets or sets the <see cref="T:NesConfigurationProfile"/> at the specified index.
        /// </summary>
        /// <value></value>
        public NesConfigurationProfile this[int index]
        {
            get
            {
                return _Profiles[index];
            }
            set
            {
                throw new NotSupportedException();
            }
        }
        /// <summary>
        /// Gets the number of elements contained in the <see cref="T:System.Collections.Generic.ICollection`1"></see>.
        /// </summary>
        /// <value></value>
        /// <returns>The number of elements contained in the <see cref="T:System.Collections.Generic.ICollection`1"></see>.</returns>
        public int Count
        {
            get
            {
                return _Profiles.Count;
            }
        }

        /// <summary>
        /// Gets a value indicating whether the <see cref="T:System.Collections.Generic.ICollection`1"></see> is read-only.
        /// </summary>
        /// <value></value>
        /// <returns>true if the <see cref="T:System.Collections.Generic.ICollection`1"></see> is read-only; otherwise, false.</returns>
        public bool IsReadOnly
        {
            get
            {
                return (_Profiles as ICollection<NesConfigurationProfile>).IsReadOnly;
            }
        }


        public string NameTableImageOutputPath
        {
            get
            {
                return _NameTableImageOutputPath;
            }
            set
            {
                _NameTableImageOutputPath = value;
            }
        }

        public string PatternTableImageOutputPath
        {
            get
            {
                return _PatternTableOutputPath;
            }
            set
            {
                _PatternTableOutputPath = value;
            }
        }
    
        public string LastRomFilePath
        {
            get
            {
                if (_LastRomFilepath == null ||
                    !Directory.Exists(_LastRomFilepath))
                {
                    _LastRomFilepath = FallbackDirectory;
                }
                return _LastRomFilepath;
            }
            set
            {
                if (_LastRomFilepath == null ||
                    !Directory.Exists(_LastRomFilepath))
                {
                    _LastRomFilepath = FallbackDirectory;
                    return;
                }

                _LastRomFilepath = value;
            }
        }

        private string FallbackDirectory
        {
            get
            {
                return Path.GetDirectoryName(typeof(NesConfigurationStore).Assembly.Location);
            }
        }

        #endregion Properties

        #region Methods

        public void Save()
        {
        }

        public void Save(string fileName)
        {

        }

        private void Read(string fileName)
        {
        }

        private void Read(Stream stream)
        {
        }



        #region IList<NesConfigurationProfile>

        /// <summary>
        /// Adds an item to the <see cref="T:System.Collections.Generic.ICollection`1"></see>.
        /// </summary>
        /// <param name="item">The object to add to the <see cref="T:System.Collections.Generic.ICollection`1"></see>.</param>
        /// <exception cref="T:System.NotSupportedException">The <see cref="T:System.Collections.Generic.ICollection`1"></see> is read-only.</exception>
        public void Add(NesConfigurationProfile item)
        {
            // Check if null.
            if (item == null)
            {
                throw new ArgumentNullException("item", "The item cannot be null !");
            }

            // Make sure not dupe.
            if (_Profiles.Find(
                 delegate(NesConfigurationProfile profile)
                 { return profile.Name == item.Name; }) != null)
            {
                throw new ArgumentException(
                    "A profile with the same name already exists !", "item"
                );
            }

            // Add the item.
            _Profiles.Add(item);
        }


        /// <summary>
        /// Determines the index of a specific item in the <see cref="T:System.Collections.Generic.IList`1"></see>.
        /// </summary>
        /// <param name="item">The object to locate in the <see cref="T:System.Collections.Generic.IList`1"></see>.</param>
        /// <returns>
        /// The index of item if found in the list; otherwise, -1.
        /// </returns>
        public int IndexOf(NesConfigurationProfile item)
        {
            return _Profiles.IndexOf(item);
        }

        /// <summary>
        /// Inserts an item to the <see cref="T:System.Collections.Generic.IList`1"></see> at the specified index.
        /// </summary>
        /// <param name="index">The zero-based index at which item should be inserted.</param>
        /// <param name="item">The object to insert into the <see cref="T:System.Collections.Generic.IList`1"></see>.</param>
        /// <exception cref="T:System.NotSupportedException">The <see cref="T:System.Collections.Generic.IList`1"></see> is read-only.</exception>
        /// <exception cref="T:System.ArgumentOutOfRangeException">index is not a valid index in the <see cref="T:System.Collections.Generic.IList`1"></see>.</exception>
        public void Insert(int index, NesConfigurationProfile item)
        {
            _Profiles.Insert(index, item);
        }

        /// <summary>
        /// Removes the <see cref="T:System.Collections.Generic.IList`1"></see> item at the specified index.
        /// </summary>
        /// <param name="index">The zero-based index of the item to remove.</param>
        /// <exception cref="T:System.NotSupportedException">The <see cref="T:System.Collections.Generic.IList`1"></see> is read-only.</exception>
        /// <exception cref="T:System.ArgumentOutOfRangeException">index is not a valid index in the <see cref="T:System.Collections.Generic.IList`1"></see>.</exception>
        public void RemoveAt(int index)
        {
            _Profiles.RemoveAt(index);
        }



        /// <summary>
        /// Removes all items from the <see cref="T:System.Collections.Generic.ICollection`1"></see>.
        /// </summary>
        /// <exception cref="T:System.NotSupportedException">The <see cref="T:System.Collections.Generic.ICollection`1"></see> is read-only. </exception>
        public void Clear()
        {
            _Profiles.Clear();
        }

        /// <summary>
        /// Determines whether the <see cref="T:System.Collections.Generic.ICollection`1"></see> contains a specific value.
        /// </summary>
        /// <param name="item">The object to locate in the <see cref="T:System.Collections.Generic.ICollection`1"></see>.</param>
        /// <returns>
        /// true if item is found in the <see cref="T:System.Collections.Generic.ICollection`1"></see>; otherwise, false.
        /// </returns>
        public bool Contains(NesConfigurationProfile item)
        {
            return _Profiles.Contains(item);
        }

        /// <summary>
        /// Copies the elements of the <see cref="T:System.Collections.Generic.ICollection`1"></see> to an <see cref="T:System.Array"></see>, starting at a particular <see cref="T:System.Array"></see> index.
        /// </summary>
        /// <param name="array">The one-dimensional <see cref="T:System.Array"></see> that is the destination of the elements copied from <see cref="T:System.Collections.Generic.ICollection`1"></see>. The <see cref="T:System.Array"></see> must have zero-based indexing.</param>
        /// <param name="arrayIndex">The zero-based index in array at which copying begins.</param>
        /// <exception cref="T:System.ArgumentOutOfRangeException">arrayIndex is less than 0.</exception>
        /// <exception cref="T:System.ArgumentNullException">array is null.</exception>
        /// <exception cref="T:System.ArgumentException">array is multidimensional.-or-arrayIndex is equal to or greater than the length of array.-or-The number of elements in the source <see cref="T:System.Collections.Generic.ICollection`1"></see> is greater than the available space from arrayIndex to the end of the destination array.-or-Type T cannot be cast automatically to the type of the destination array.</exception>
        public void CopyTo(NesConfigurationProfile[] array, int arrayIndex)
        {
            throw new Exception("The method or operation is not implemented.");
        }

       
        /// <summary>
        /// Removes the first occurrence of a specific object from the <see cref="T:System.Collections.Generic.ICollection`1"></see>.
        /// </summary>
        /// <param name="item">The object to remove from the <see cref="T:System.Collections.Generic.ICollection`1"></see>.</param>
        /// <returns>
        /// true if item was successfully removed from the <see cref="T:System.Collections.Generic.ICollection`1"></see>; otherwise, false. This method also returns false if item is not found in the original <see cref="T:System.Collections.Generic.ICollection`1"></see>.
        /// </returns>
        /// <exception cref="T:System.NotSupportedException">The <see cref="T:System.Collections.Generic.ICollection`1"></see> is read-only.</exception>
        public bool Remove(NesConfigurationProfile item)
        {

            return _Profiles.Remove(item);
        }

        /// <summary>
        /// Returns an enumerator that iterates through the collection.
        /// </summary>
        /// <returns>
        /// A <see cref="T:System.Collections.Generic.IEnumerator`1"></see> that can be used to iterate through the collection.
        /// </returns>
        public IEnumerator<NesConfigurationProfile> GetEnumerator()
        {
            return _Profiles.GetEnumerator();
        }

        /// <summary>
        /// Returns an enumerator that iterates through a collection.
        /// </summary>
        /// <returns>
        /// An <see cref="T:System.Collections.IEnumerator"></see> object that can be used to iterate through the collection.
        /// </returns>
        System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
        {
            return _Profiles.GetEnumerator();
        }
        #endregion IList<NesConfigurationProfile>

        #endregion Methods
    }
}
